package com.itmuch.demoprovider;

import com.itmuch.demoprovider.feign.BaiduFeignClient;
import com.itmuch.demoprovider.feign.DemoProviderFeignClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * demo-provider
 * corePoolSize=5, maxiumPoolSize=10, queue=5
 */
@Slf4j
@RestController
public class ConumserTestController {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;

    private AtomicInteger count = new AtomicInteger(0);

    // 调用provider接口
    @GetMapping("/consumer-hello-world")
    public String hello() {
        // "demo-provider"微服务所有实例的地址
        List<ServiceInstance> instances = discoveryClient.getInstances("demo-provider");

        int andIncrement = count.getAndIncrement();
        URI uri = instances.get(andIncrement % instances.size())
            .getUri();

        String url = uri + "/hello-world";
        log.info("url = {}", url);

        return "consumer: " + restTemplate.getForObject(
            url,
            String.class
        );
    }

    /**
     * 1. 超时机制：1s
     * 2. 限流 没有直接实现
     * 3. 仓壁模式 corePoolSize=5, maxiumPoolSize=10, queue=5
     * 4. 断路器 5s内，错误率达到50%，次数达到20次
     *
     * @return
     */
    @HystrixCommand(fallbackMethod = "ribbonFallback")
    @GetMapping("/ribbon-hello-world")
    public String ribbon() {
        return "consumer: " + restTemplate.getForObject(
            // ribbon将demo-provider识别成虚拟主机名
            // 再用这个名称到eureka server获取微服务实例信息[本地缓存] {列表}
            // 使用ribbon的负载均衡算法，算出来1个实例，交给resttemplate

            // 1. 复杂url难维护
            // https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=asdf&fenlei=256&rsv_pq=953597ed0000698e&rsv_t=3983NNRA2sdUW6ugSzfomPRfAosVwSYD2wLQ4f45EshjMrjy8y3lJvVMP4U&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=5&rsv_sug1=2&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&prefixsug=asdf&rsp=2&inputT=591&rsv_sug4=591
            // 2. 动态url 难维护
            // 3. 开发体验不统一
            // 4. 代码风格不统一
            "http://demo-provider/hello-world",
            String.class
        );
    }

    public String ribbonFallback(Throwable throwable) {
        log.error("业务降级了...", throwable);
        // 后备措施
        return "fallback...";
    }

    @Autowired
    private DemoProviderFeignClient demoProviderFeignClient;

    @GetMapping("/feign-hello-world")
    public String feign() {
        return "feign consumer: " + this.demoProviderFeignClient.hello();
    }

    @Autowired
    private BaiduFeignClient baiduFeignClient;

    @GetMapping("/baidu")
    public String baidu() {
        return "feign consumer: " + this.baiduFeignClient.index();
    }
}
